﻿/**
 * Reboulder - Partial Boulder Dash clone
 * Jesús Sagra, 2014
 * 
 * Game class: game logic
 * 
 * Version    Date     Changes
 * -----------------------------------------------------
 *  0.01   07-dic-2014  Methods: Run(skeleton), DrawElements, CheckInput, 
 *                               WaitForNextFrame. 
 *  0.02   08-dic-2014  Check collisons with background at CheckInput.
 *  0.03   08-dic-2014  Pick items and clear sand gives points. Clear picked item.
 *                      Clear sand when player crosses it.
 *                      Method: CheckCollisions.
 */

using System.Collections.Generic;
class Game
{
    protected bool finished;
    protected Map myMap;
    protected ScoreBar scores;
    protected Sprite[,] sprites;
    protected Player player1;
    protected int itemsCount;
    //protected HiScores hiScores;

    public Game()
    {
        finished = false;
        myMap = new Map();
        sprites = new Sprite[myMap.GetMapHeight(), myMap.GetMapWidth()];
        ReadMap();
        scores = new ScoreBar(itemsCount,
            player1.GetLives());
    }


    public void Run()
    {
        // Game Loop
        do
        {
            // Update screen
            DrawElements();

            // Check input by the user
            CheckInput();

            // Move enemies, background, etc 
            MoveElements();

            // Check collisions and apply game logic
            CheckCollisions();

            // Pause till next frame
            WaitForNextFrame();
        }
        while (!finished);

        //TO DO
        //HiScores
    }


    public void DrawElements()
    {
        SdlHardware.ClearScreen();
        //Scorebar
        scores.DrawOnHiddenScreen();
        //All sprites
        foreach (Sprite sprite in sprites)
        {
            sprite.DrawOnHiddenScreen();
        }
        SdlHardware.ShowHiddenScreen();
    }

    public void CheckInput()
    {
        if (SdlHardware.KeyPressed(SdlHardware.KEY_RIGHT))
            TryMoveTo("right");
        else if (SdlHardware.KeyPressed(SdlHardware.KEY_LEFT))
            TryMoveTo("left");
        else if (SdlHardware.KeyPressed(SdlHardware.KEY_DOWN))
            TryMoveTo("down");
        else if (SdlHardware.KeyPressed(SdlHardware.KEY_UP))
            TryMoveTo("up");
        else if (SdlHardware.KeyPressed(SdlHardware.KEY_ESC))
            finished = true;
    }

    public void MoveElements()
    {
        //TO DO
    }

    public void CheckCollisions()
    {
        
    }


    // Pause till next frame (40 ms = 25 fps)
    public static void WaitForNextFrame()
    {
        SdlHardware.Pause(80);
    }





    public void MovePlayer(string option)
    {
       switch (option)
        {
            case "right":
                player1.MoveRight();
                break;
            case "left":
                player1.MoveLeft();
                break;
            case "up":
                player1.MoveUp();
                break;
            case "down":
                player1.MoveDown();
                break;
        }
        
    }



    public void TryMoveTo(string option)
    {
        int row = player1.GetRow();
        int col = player1.GetCol();
        int backgroundTileSize = 32; 

        switch (option)
        {
            case "right":
                col ++;
                break;
            case "left":
                col-- ;
                break;
            case "up":
                row --;
                break;
            case "down":
                row++;
                break;
        }

        string objType = sprites[row, col].ToString();

        switch (objType)
        {
            case "sand":

                sprites[player1.GetRow(), player1.GetCol()] = null;
                //sprites[player1.GetRow(), player1.GetCol()] = new Sand((Sand)sprites[row, col]);
                sprites[player1.GetRow(), player1.GetCol()] = new Sand(col * backgroundTileSize,
                        row * backgroundTileSize );
                sprites[player1.GetRow(), player1.GetCol()].Hide();
                sprites[row, col] = player1;
                MovePlayer(option);
            
                break;
            case "item":

                
                int auxScore =  ((Item)sprites[row, col]).GetScore();

                sprites[player1.GetRow(), player1.GetCol()] = null;
                sprites[player1.GetRow(), player1.GetCol()] = new Sand(col * backgroundTileSize,
                        row * backgroundTileSize );
                sprites[player1.GetRow(), player1.GetCol()].Hide();
                sprites[row, col] = player1;
                scores.SetScore(auxScore);
                scores.SetPickedItems();
                MovePlayer(option);

                break;
        }
}




    public void ReadMap()
    {
        int mapHeight = myMap.GetMapHeight();
        int mapWidth = myMap.GetMapWidth();
        sprites = new Sprite[mapHeight, mapWidth];
        string[] level = myMap.GetLevel();
        int backgroundTileSize = 32;
        for (int row = 0; row < mapHeight; row++)
        {
            for (int col = 0; col < mapWidth; col++)
            {
                switch (level[row][col])
                {
                    case '@':
                        sprites[row, col] = new Door(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        break;
                    case 'O':
                        sprites[row, col] = new Rock(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        break;
                    case '_':
                        sprites[row, col] = new Sand(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        break;
                    case 'X':
                        sprites[row, col] = new Item(col * backgroundTileSize,
                        row * backgroundTileSize + 32, 100);
                        itemsCount++;
                        break;
                    case 'B':
                        sprites[row, col] = new Brick(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        break;
                    case 'P':
                        player1 = new Player(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        sprites[row, col] = player1;
                        break;
                    case '#':
                        sprites[row, col] = new Wall(col * backgroundTileSize,
                        row * backgroundTileSize + 32);
                        break;
                }
            }
        } 
    }
}